JavaScript - Frameworks and Libraries

Next.js

  • <script>&&& ping bong !!!</script>

  • Built on React.

Component-based Frameworks

  • Almost all frontend frameworks are syntax/ergonomic sugar on top of native JS and the browser.

  • None add fundamentally new runtime capabilities that the browser can’t already do.

  • .

  • No JS framework suddenly gives threads, parallel execution, or new DOM APIs.

  • They cannot extend what the browser can do.

  • Why frameworks exist :

    • They reduce repetitive wiring for large apps.

    • They integrate state, DOM updates, and async requests in a structured way.

    • They handle edge cases (race conditions, lifecycle, error states, component reuse) that become messy in raw JS.

    • Automate common patterns

    • Reduce bugs and boilerplate

    • Provide a declarative programming model

Comparisons
  • Reactivity : React/Preact use component-level state and rerender subtree. Solid uses signals; updates are localized. Qwik uses signals/refs but focuses on serializing and lazy event handlers.

  • Rendering : React/Preact VDOM diff. Solid direct DOM ops (compiled). Qwik renders on server then resumes only what’s needed.

  • Hydration : React/Preact full or partial hydration. Solid partial hydration techniques. Qwik aims for no traditional hydration — it resumes.

  • Bundle/runtime : Preact < React (smaller). Solid small runtime for reactivity. Qwik pushes logic to server/serialized payload; runtime focuses on resuming.

  • Use case : React/Preact good for heavy interactivity and library ecosystem. Solid for maximum update performance. Qwik for extreme lazy-load and fast TTFP.

Vanilla JS (Not a framework, I'm just comparing)

Characteristics
  • AJAX:

    • fetch()  or XMLHttpRequest  (older API).

  • Problems appear as you scale:

    • Multiple endpoints → repeated fetch calls.

    • Multiple components updating DOM → repeated innerHTML  updates.

    • Error handling → repeated try/catch blocks.

    • State management → you must track which component has which data.

    • UI updates tied to async → manually coordinate loading states, spinners, etc.

Examples
  • More complex async behavior :

    const widgets = [
      { id: "widget1", url: "/data1" },
      { id: "widget2", url: "/data2" },
      { id: "widget3", url: "/data3" },
    ];
    
    const status = document.getElementById("status");
    
    let completed = 0;
    
    widgets.forEach(w => {
      const el = document.getElementById(w.id);
      el.innerHTML = "Loading...";
    
      fetch(w.url)
        .then(res => {
          if (!res.ok) throw new Error("Network error");
          return res.text();
        })
        .then(html => {
          el.innerHTML = html;
        })
        .catch(err => {
          el.innerHTML = "Error loading widget";
          console.error(err);
        })
        .finally(() => {
          completed++;
          if (completed === widgets.length) {
            status.innerHTML = "Dashboard loaded";
          }
        });
    });
    

Svelte

  • No Virtual DOM.

  • Works as a compiler, to turn the .svelte  code into plain JS.

  • Full TypeScript support ( .svelte  files with <script lang="ts"> )

  • Compile-time type checking on props, stores, and events

  • 1 component per file.

  • Every .svelte  file has 3 parts:

    • script + markup + style.

  • Very fast runtime, small bundle

  • AJAX:

    • Fetch or load  functions use AJAX under the hood.

Examples
  • Button increases a counter :

<script>
  let count = 0;
  const increment = () => count++;
</script>

<p>Count: {count}</p>
<button on:click={increment}>Increment</button>
  • Ex2 :

<script>
  export let items = [];
</script>

{#if items.length}
  <ul>
    {#each items as item}
      <li>{item.title}</li>
    {/each}
  </ul>
{:else}
  <div>No items</div>
{/if}

Qwik

  • .

Solid

  • No Virtual DOM.

  • Similar to React.

  • Uses JSX.

  • Kinda like React, but with a Svelte-like compiler

  • "A more well thought-out and faster version of React".

Examples
  • Button increases a counter :

import { createSignal } from 'https://cdn.skypack.dev/solid-js';
import { render } from 'https://cdn.skypack.dev/solid-js/web';

function Counter() {
  const [count, setCount] = createSignal(0);
  return (
    <div>
      <p>Count: {count()}</p>
      <button onClick={() => setCount(count() + 1)}>Increment</button>
    </div>
  );
}

render(() => <Counter >, document.getElementById('app'));
  • Ex2 :

import { For, Show } from "solid-js";

export default function List(props) {
  return (
    <Show when={props.items.length} fallback={<div>No items</div>}>
      <ul>
        <For each={props.items}>{item => <li>{item.title}</li>}</For>
      </ul>
    </Show>
  );
}
import { For } from "solid-js";

export default function Users(props) {
  return <ul><For each={props.users}>{u => <li>{u.name}</li>}</For></ul>;
}

Vue

  • React's components, Angular's templates.

  • A .vue  file is:

    • Template + Script + Style

Characteristics
  • Has Virtual DOM.

  • AJAX:

    • Vue itself doesn’t do AJAX, but most Vue apps use it for components.

Examples
  • Button increases a counter :

<div id="app">
  <p>Count: {{ count }}</p>
  <button @click="increment">Increment</button>
</div>

<script type="module">
import { createApp, ref } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js';

const App = {
  setup() {
    const count = ref(0);
    const increment = () => count.value++;
    return { count, increment };
  }
};

createApp(App).mount('#app');
</script>
  • Ex2 :

<template>
  <div>
    <ul v-if="items.length">
      <li v-for="item in items" :key="item.id">{{ item.title }}</li>
    </ul>
    <div v-else>No items</div>
  </div>
</template>

<script setup>
defineProps({ items: Array });
</script>

Preact

  • React-compatible API, smaller runtime.

  • Has Virtual DOM.

  • Uses JSX.

Examples
  • Button increases a counter :

import { h, render } from 'https://unpkg.com/preact@latest?module';
import { useState } from 'https://unpkg.com/preact@latest/hooks/dist/hooks.mjs?module';

function Counter() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

render(<Counter >, document.getElementById('app'));

React

  • From Facebook, 2013.

  • Uses JSX.

  • Has Virtual DOM.

  • Svelte or Solid sounds much better than this thing.

  • AJAX:

    • Via fetch , Axios, or libraries like React Query; client-side rendering is driven by async data.

Asynchronous Behavior
  • React doesn’t fundamentally change how concurrency works—JS is still single-threaded—but it improves ergonomics and state management around asynchronous operations

  • React doesn’t add new concurrency primitives—it doesn’t give JS threads, parallelism, or async I/O that didn’t exist.

  • Everything React does is built on native JS: Promises, the event loop, fetch , timers, etc.

  • Automatic DOM diffing  â†’ no manual innerHTML  manipulation.

    • Your component re-renders automatically when state changes.

    • In Vanilla JS :

      fetch("/data")
        .then(res => res.text())
        .then(html => document.getElementById("widget").innerHTML = html);
      
      • You must track which element corresponds to which data.

      • Any additional async operations updating the same element require careful coordination.

    • In React :

      const [data, setData] = useState(null);
      
      useEffect(() => {
        fetch("/data")
          .then(res => res.text())
          .then(setData);
      }, []);
      
      return <div>{data || "Loading..."}</div>;
      
      • React automatically re-renders the component when state changes.

      • No manual DOM manipulation.

      • Concurrency conflicts are minimized because state updates are batched and applied in order.

Examples
  • Button increases a counter :

import { useState } from "react";
import { createRoot } from "react-dom/client";

function Counter() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

const root = createRoot(document.getElementById("app"));
root.render(<Counter >);
  • Simple async behavior :

function Component() {
  const [data, setData] = React.useState(null);

  React.useEffect(() => {
    fetch("/data")
      .then(res => res.json())
      .then(setData);
  }, []);

  return <div>{data}</div>;
}
  • More complex async behavior :

    function Dashboard() {
      const [widgets, setWidgets] = React.useState([]);
      const [loaded, setLoaded] = React.useState(false);
    
      React.useEffect(() => {
        Promise.all([
          fetch("/data1").then(r => r.text()),
          fetch("/data2").then(r => r.text()),
          fetch("/data3").then(r => r.text()),
        ])
          .then(results => setWidgets(results))
          .finally(() => setLoaded(true));
      }, []);
    
      return (
        <div>
          {widgets.map((w, i) => (
            <div key={i}>{w || "Loading..."}</div>
          ))}
          {loaded && <div>Dashboard loaded</div>}
        </div>
      );
    }
    

Angular

  • Google, 2010.

  • Angular 2 in 2016.

  • Requires TS.

Characteristics
  • Has Virtual DOM.

  • Reactivity model: Change detection.

  • AJAX:

    • Has built-in HttpClient  for AJAX requests; components update via async data.

  • Template syntax, but bound tightly to TypeScript logic.

// user-list.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'user-list',
  template: `
    <ul>
      <li *ngFor="let u of users">{{ u.name }}</li>
    </ul>
  `
})
export class UserListComponent {
  users = [{ id:1, name:'Alice' }, { id:2, name:'Bob' }];
}
Examples
  • Button increases a counter :

// counter.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-counter',
  template: `
    <p>Count: {{ count }}</p>
    <button (click)="increment()">Increment</button>
  `
})
export class CounterComponent {
  count = 0;
  increment() { this.count++; }
}

// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { CounterComponent } from './counter.component';

@NgModule({
  declarations: [CounterComponent],
  imports: [BrowserModule],
  bootstrap: [CounterComponent]
})
export class AppModule {}

Backbone

Ember

  • Convention over configuration.

Lit

  • Google.

  • Focused on Web Components.

Stencil

  • Focused on Web Components.

Mithril

  • Virtual DOM.

Libraries

HTMX

Alpine.js / Alpine AJAX

  • Popular replacement of JQuery.

Alphine AJAX
<div x-data>
  <button x-on:click="$ajax.get('/users').then(html => $refs.list.innerHTML = html)">
    Load Users
  </button>
  <div x-ref="list"></div>
</div>
Alphine.js
<div x-data="{ open: false }">
  <button @click="open = !open">Toggle</button>
  <p x-show="open">Now visible</p>
</div>

JQuery

Characteristics
  • AJAX:

    • .ajax() , .get() , .post()  provide AJAX out of the box.

    $.get("/data", function(html) {
      $("#result").html(html);
    });
    
    • Wraps XMLHttpRequest  or fetch internally.

    • Provides cross-browser normalization .

    • Simplifies DOM selection and updates ( $("#id") ).

    • Handles callbacks inline.

    • At scale, it avoids repeated verbose fetch()  + innerHTML  calls.

Web-Frameworks

ExpressJS

Exemplos
  • GET básico:

    import express from 'npm:express';
    
    const app = express();
    
    app.get('/', (req: express.Request, res: express.Response) => {
        res.send('Hello World!');
    });
    
    app.listen(3000, () => {
        console.log('Server is running on http://localhost:3000');
    });
    
  • GET com body:

    import express from 'npm:express';
    
    const app = express();
    
    app.use(express.json());
    
    app.get('/oi', (req: express.Request, res: express.Response) => {
        console.log(request.body);
        
        res.send('Hello World!');
    });
    
    app.listen(3000, () => {
        console.log('Server is running on http://localhost:3000');
    });
    
  • GET com "Router":

    • Supostamente Ă© tipo pastas da URL.

    • A URL completa Ă© no formato https://discord.com/api/v9/channels

    import express from 'npm:express';
    
    const app = express();
    
    app.use(express.json());
    
    const api = express.Router();
    api.get('/channels', (request: express.Request, response: express.Response) => {
    });
    api.get('/users', (request: express.Request, response: express.Response) => {
    });
    api.use('/api/v9', api);
    
    
    app.listen(3000, () => {
        console.log('Server is running on http://localhost:3000');
    });
    
  • GET com ID:

    import express from 'npm:express';
    
    const app = express();
    
    app.use(express.json());
    
    app.get('/produtos/:id', (request: express.Request, response: express.Response) => {
        const {id} = request.params;
        
        res.send(`ID pedido: ${id}`);
    });
    
    app.listen(3000, () => {
        console.log('Server is running on http://localhost:3000');
    });
    
Status
  • **Regras:

    • No Express, vocĂŞ sĂł pode enviar uma Ăşnica resposta para cada requisição, seja ela JSON, texto ou qualquer outro formato.

    • No Express, para evitar o timeout, vocĂŞ deve sempre enviar uma resposta completa  usando um dos mĂ©todos como res.send , res.json , ou res.end .

      • Enviar apenas res.status(200);  nĂŁo Ă© suficiente no Express. Esse comando define o cĂłdigo de status HTTP  para a resposta, mas nĂŁo a encerra nem envia conteĂşdo. O cliente continuará aguardando atĂ© o timeout porque nenhuma resposta final foi enviada.

  • **Boas práticas:

    • Nunca chame res.send , res.json  ou res.end  mais de uma vez na mesma requisição.

    • Use console.log  ou uma biblioteca como Winston  para registrar logs do servidor.

  • Uso do status:

    res.status(200).json(personagem);  // Explicitamente define que o Status Ă© 200.
    res.json(personagem);              // Implicitamente define o Status padrĂŁo, que Ă© 200.
    
  • .send:

    • Envia uma resposta ao cliente, que pode incluir um corpo de mensagem ( body ).

    • Ele formata automaticamente o conteĂşdo, como strings, objetos JSON, buffers ou nĂşmeros.

    • Finaliza a resposta apĂłs o envio.

    • Se usado sem parâmetros ( res.send() ), ele enviará um corpo vazio ( ' '  ou equivalente a null ) e definirá automaticamente o cabeçalho Content-Length  como 0 .

    • Pode inferir o tipo de conteĂşdo e ajustar o cabeçalho Content-Type  automaticamente.

    res.send(); // Envia uma resposta com corpo vazio e encerra
    res.send('Hello World'); // Envia uma string
    res.send({ message: 'Hello World' }); // Envia um objeto JSON
    
  • .end:

    • Finaliza a resposta HTTP sem adicionar cabeçalhos ou fazer formatação adicional.

    • Pode incluir dados diretamente como um buffer ou string, mas nĂŁo faz formatação automática.

    • NĂŁo define automaticamente o cabeçalho Content-Type .

    • NĂŁo faz formatação ou inferĂŞncia do conteĂşdo.

    • É Ăştil para cenários de respostas de baixo nĂ­vel.

    res.end(); // Finaliza a resposta sem enviar conteĂşdo
    res.end('Hello World'); // Envia a string e finaliza
    res.end(Buffer.from('Hello World')); // Envia um buffer e finaliza
    
  • **.json:

    • O .json()  converte um objeto JavaScript (ou um valor) para o formato JSON e envia a resposta.

    • Ele define automaticamente o cabeçalho Content-Type  da resposta como application/json , informando ao cliente que a resposta contĂ©m dados no formato JSON.

    • TambĂ©m converte o objeto JavaScript para uma string JSON, o que permite que os dados sejam facilmente lidos e interpretados por clientes como navegadores, APIs, ou aplicativos.

    res.json(data);
    
  • Exemplo 1:

    • NĂŁo funciona:

    res.status(500).json({ message: (error as Error).message }); 
    res.send('(get_personagem) Find com erro.');  // Essa linha será ignorada.
    
    • Funciona:

    res.status(500).json({ 
        message: (error as Error).message,
        log: '(get_personagem) Find com erro.'
    });
    
  • Exemplo 2:

    • Funciona:

    res.status(200).send('(put_criaturas) Sucesso.\n');
    
    res.status(200).send(); // Responde com 200 e sem conteĂşdo
    
    • NĂŁo funciona:

    res.status(200);
    

Oak (Deno)

Deno Serve Deno.serve(...)

  • .

Databases

Mongoose

About
  • Mongoose .

  • It's a wrapper for MongoDB.

  • Is Mongoose an ORM?

    • Mongoose is not technically an ORM (Object-Relational Mapping), but rather an ODM (Object-Document Mapping).

    • Although both ORM and ODM have similar goals — mapping objects in code to database entities — the difference is the type of database each one handles.

Explanations
Database
  • How to rename a Database .

    • I don't really know yet where the DB lives on the filesystem.

      • There are files inside Program Files/mongodb .

Schemas and Models
  • Creating a Schema and Model:

import mongoose from 'npm:mongoose';

mongoose.connect('mongodb://localhost/meu_banco', { useNewUrlParser: true, useUnifiedTopology: true });

const usuarioSchema = new mongoose.Schema({
  nome: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  idade: { type: Number, min: 18 }
});

const Usuario = mongoose.model('Usuario', usuarioSchema);
  • Collection name:

    • .

Documents
  • Via new Model  and .save

const new_user = new Usuario({
  nome: 'John',
  email: 'john@email.com',
  idade: 25
});

new_user.save()
  .then(() => console.log('User saved!'))
  .catch((err) => console.log('Error saving the user:', err));
  • Via .create :

const new_character = await Character.create({
    nome: 'John',
});
Validations
  • Taken from the video above .

  • A schema created by default has its properties set as 'not required'.

  • .

  • .

  • .

  • .